package com.un.ebs.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.un.ebs.core.UserContext;
import com.un.ebs.core.enums.ScopeEnum;
import com.un.ebs.core.exception.BusinessEntityNotFoundException;
import com.un.ebs.core.util.SecurityUtils;
import com.un.ebs.sys.domain.DictionaryKey;
import com.un.ebs.sys.domain.DictionaryValue;
import com.un.ebs.sys.domain.DictionaryValueExt;
import com.un.ebs.sys.dto.DictionaryValueAddDto;
import com.un.ebs.sys.dto.DictionaryValueUpdateDto;
import com.un.ebs.sys.dto.ObjectParentAndIndexChangeDto;
import com.un.ebs.sys.mapper.DictionaryKeyMapper;
import com.un.ebs.sys.mapper.DictionaryValueExtMapper;
import com.un.ebs.sys.mapper.DictionaryValueMapper;
import com.un.ebs.sys.service.DictionaryKeyService;
import com.un.ebs.sys.service.DictionaryValueService;
import com.un.ebs.sys.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author liubo
 * @since 2019-09-25
 */
@Service
public class DictionaryValueServiceImpl extends ServiceImpl<DictionaryValueMapper, DictionaryValue> implements DictionaryValueService {

//    @Autowired
//    private RedisService redisService;

    @Autowired
    private DictionaryKeyMapper dictionaryKeyMapper;

    @Autowired
    private DictionaryValueExtMapper dictionaryValueExtMapper;

    @Autowired
    private DictionaryKeyService dictionaryKeyService;

    @Autowired
    private DictionaryValueMapper dictionaryValueMapper;

    //private String dictKeyPrefix = "DictionValue:";

    //@CacheEvict(cacheNames = "dict_value", allEntries = true)

    private String getCacheKey(String dictCode) {
        return String.format("DictionValue:%s:%s", SecurityUtils.getTenantId(), dictCode);
    }

    @Override
    public void add(DictionaryValueAddDto req) {
        DictionaryKey key = dictionaryKeyService.queryById(req.getKeyId());
        if (key == null) {
            throw new BusinessEntityNotFoundException(req.getKeyId(), "DictionaryKey");
        }

        DictionaryValue obj = new DictionaryValue();
        obj.setKeyId(req.getKeyId());
        obj.setValue(req.getValue());
        obj.setDescription(req.getDescription());
        obj.setIsDelete(false);
        obj.setAppId(SecurityUtils.getUserContent().getAppId());
        obj.setParentId(req.getParentId());
        if (StringUtils.isEmpty(req.getParentId())) {
            obj.setSort(getBaseMapper().maxSort());
        } else {
            obj.setSort(getBaseMapper().maxSortByParentId(req.getParentId()));
        }
        obj.insert();

//        //删除当前缓存
//        redisService.remove(getCacheKey(key.getCode()));
    }

    //@CacheEvict(cacheNames = "dict_value", allEntries = true)
    @Override
    public void add(String key, String value, String desc) {
        DictionaryKey objKey = dictionaryKeyService.queryByKey(key);
        if (objKey == null) {
            throw new BusinessEntityNotFoundException(key, "DictionaryKey");
        }

        LambdaQueryWrapper<DictionaryValue> lq = Wrappers.lambdaQuery();
        lq.eq(DictionaryValue::getKeyId, objKey.getId());
        lq.eq(DictionaryValue::getValue, value);
        lq.eq(DictionaryValue::getTenantId, SecurityUtils.getTenantId());
        DictionaryValue obj = dictionaryValueMapper.selectOne(lq);

        if (obj == null) {
            obj = new DictionaryValue();
            obj.setKeyId(objKey.getId());
            obj.setValue(value);
            obj.setDescription(com.un.ebs.core.util.StringUtils.isNullOrEmpty(desc) ? value : desc);
            obj.setIsDelete(false);
            obj.setAppId(SecurityUtils.getUserContent().getAppId());
            obj.setSort(getBaseMapper().maxSort());
            obj.insert();
        }
//        //删除当前缓存
//        redisService.remove(getCacheKey(objKey.getCode()));
    }

    //@CacheEvict(cacheNames = "dict_value", allEntries = true)
    @Override
    public void update(DictionaryValueUpdateDto req) {

        DictionaryValue obj = getById(req.getId());
        if (!StringUtils.isEmpty(req.getKeyId())) {
            obj.setKeyId(req.getKeyId());
        }
        obj.setValue(req.getValue());
        obj.setDescription(req.getDescription());
        obj.setParentId(req.getParentId());
        obj.updateById();

        obj = getById(req.getId());
        DictionaryKey key = dictionaryKeyService.queryById(obj.getKeyId());
        if (key == null) {
            throw new BusinessEntityNotFoundException(obj.getKeyId(), "DictionaryKey");
        }

        //删除当前缓存
        //redisService.remove(getCacheKey(key.getCode()));

    }

    @Override
    public DictionaryValue queryById(String id) {
        return getBaseMapper().selectById(id);
    }

    @Transactional
    @Override
    public void changeNode(List<ObjectParentAndIndexChangeDto> nodes) {
        for (ObjectParentAndIndexChangeDto node : nodes) {
            DictionaryValue dictionaryValue = baseMapper.selectById(node.getId());
            if (dictionaryValue == null) {
                throw new BusinessEntityNotFoundException(node.getId(), "字典值");
            }
            dictionaryValue.setParentId(node.getParentId());
            dictionaryValue.setSort(node.getIndex());
            dictionaryValue.updateById();
        }
    }

    @Override
    public void delete(String id) {
        DictionaryValue value = queryById(id);
        if (value == null) {
            return;
        }
        String code = dictionaryKeyService.queryById(value.getKeyId()).getCode();
        getBaseMapper().deleteById(id);

        //删除当前缓存
        //redisService.remove(getCacheKey(code));
    }

    @Override
    public List<DictionaryValue> queryByParentId(String parentId) {
        QueryWrapper<DictionaryValue> wrapper = Wrappers.query();
        wrapper.ge("parent_id", parentId);
        return getBaseMapper().selectList(wrapper);
    }

    @Override
    public IPage<DictionaryValue> queryPageByParentId(String parentId, int pageSize, int pageIndex) {
        Page<DictionaryValue> page = new Page<>(pageIndex, pageSize);
        QueryWrapper<DictionaryValue> wrapper = Wrappers.query();
        wrapper.ge("parent_id", parentId);
        return getBaseMapper().selectPage(page, wrapper);
    }

    @Override
    public List<DictionaryValueExt> queryValueByKey(String key) {
        //List<DictionaryValueExt> result = redisService.get(getCacheKey(key));
//        if (result != null) {
//            return result;
//        }

        List<DictionaryValueExt> result;

        UserContext userContext = SecurityUtils.getUserContent();
        LambdaQueryWrapper<DictionaryKey> queryKey = Wrappers.lambdaQuery();
        queryKey.eq(DictionaryKey::getAppId, userContext.getAppId());
        queryKey.eq(DictionaryKey::getCode, key);
        DictionaryKey dictionaryKey = dictionaryKeyMapper.selectOne(queryKey);
        if (dictionaryKey == null) {
            throw new BusinessEntityNotFoundException(key, "字典");
        }

        LambdaQueryWrapper<DictionaryValueExt> query = Wrappers.lambdaQuery();
        query.eq(DictionaryValueExt::getIsDelete, false);
        if (dictionaryKey.getScope() == ScopeEnum.Application) {
            query.eq(DictionaryValueExt::getCode, key).and(obj ->
                    obj.eq(DictionaryValueExt::getAppId, userContext.getAppId()));
        } else {
            query.eq(DictionaryValueExt::getCode, key).eq(DictionaryValueExt::getAppId, userContext.getAppId())
                    .eq(DictionaryValueExt::getTenantId, userContext.getTenantId());
        }
        query.orderByAsc(DictionaryValueExt::getSort);
        result = dictionaryValueExtMapper.selectList(query);

//        redisService.set(getCacheKey(key), result, 60 * 60 * 6L);
        return result;
    }

    @Override
    public String queryValue(String dictKey, String valueCode) {
        List<DictionaryValueExt> values = queryValueByKey(dictKey);
        Optional<DictionaryValueExt> obj = values.stream().filter(s -> valueCode.equals(s.getValue())).findFirst();
        if (obj.isPresent()) {
            return obj.get().getDescription();
        } else {
            return null;
        }
    }

    @Override
    public List<String> queryDeletesByKey() {
        LambdaQueryWrapper<DictionaryValue> lq = Wrappers.lambdaQuery();
        lq.eq(DictionaryValue::getIsDelete, true);
        return baseMapper.selectList(lq).stream().map(s -> s.getId()).collect(Collectors.toList());
    }

    private void cacheCurrTenantDictKeyValue(String key) {
        //dictKeyPrefix = SecurityUtils.getUserContent().getTenantId() + ":dictKey:";

        UserContext userContext = SecurityUtils.getUserContent();
        LambdaQueryWrapper<DictionaryValueExt> queryValue = Wrappers.lambdaQuery();
        queryValue.eq(DictionaryValueExt::getIsDelete, false);
        queryValue.eq(DictionaryValueExt::getAppId, userContext.getAppId());
        queryValue.eq(DictionaryValueExt::getTenantId, userContext.getTenantId());
        if (!StringUtils.isEmpty(key)) {
            queryValue.eq(DictionaryValueExt::getCode, key);
        }

        for (DictionaryValueExt obj : dictionaryValueExtMapper.selectList(queryValue)) {
            //redisUtil.hset(dictKeyPrefix + obj.getCode(), obj.getValue(), obj.getDescription());
            //redisService.hSet(dictKeyPrefix + obj.getCode(), obj.getValue(), obj.getDescription());
            //redisService.hSet();
        }
    }

    @Override
    public boolean hasValue(String key, String value, String valueDesc, boolean isCreate) {
//        //boolean result = redisUtil.hHasKey(dictKeyPrefix + key, value);
//        boolean result = com.un.ebs.core.util.StringUtils.isNullOrEmpty((String) redisService.hGet(dictKeyPrefix + key, value));
//        if (result) {
//            return true;
//        } else {
//            if (isCreate) {
//                cacheCurrTenantDictKeyValue(key);
//                //if (!redisUtil.hHasKey(dictKeyPrefix + key, value)) {
//                if (!redisService.hasKey(dictKeyPrefix + key, value)) {
//                    add(key, value, valueDesc);
//                }
//            }
//            cacheCurrTenantDictKeyValue(null);
//        }
//
//        //return redisUtil.hHasKey(dictKeyPrefix + key, value);
//        return redisService.hasKey(dictKeyPrefix + key, value);
        return false;
    }
}